package mainwindow;
import plane.*;
import reward.AddScore;
import reward.Reward;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

public class Window extends JPanel{
    public static int HEIGHT = 700;
    public static int WIDTH = 400;
    //public static int life = 3, score = 0;
    public static final int START = 0,RUNNING = 1,PAUSE = 2,GAME_OVER = 3;
    public static int now = 0;
    public static Timer timer = new Timer();

    public Window(){}

    static {
        bg = quickRead("../images/background.png");
        start = quickRead("../images/start.png");
        pause = quickRead("../images/pause.png");
        gameover = quickRead("../images/gameover.png");
        airplane = quickRead("../images/airplane.png");
        bee = quickRead("../images/bee.png");
        bigplane = quickRead("../images/bigplane.png");
        hero0 = quickRead("../images/hero0.png");
        hero1 = quickRead("../images/hero1.png");
        bullet = quickRead("../images/bullet.png");

        airplane_ember0 = quickRead("../images/airplane_ember0.png");
        airplane_ember1 = quickRead("../images/airplane_ember1.png");
        airplane_ember2 = quickRead("../images/airplane_ember2.png");
        airplane_ember3 = quickRead("../images/airplane_ember3.png");

        bigplane_ember0 = quickRead("../images/bigplane_ember0.png");
        bigplane_ember1 = quickRead("../images/bigplane_ember1.png");
        bigplane_ember2 = quickRead("../images/bigplane_ember2.png");
        bigplane_ember3 = quickRead("../images/bigplane_ember3.png");

        bee_ember0 = quickRead("../images/bee_ember0.png");
        bee_ember1 = quickRead("../images/bee_ember1.png");
        bee_ember2 = quickRead("../images/bee_ember2.png");
        bee_ember3 = quickRead("../images/bee_ember3.png");

    }
    public static BufferedImage quickRead(String str){
        try {
            return ImageIO.read(Window.class.getResourceAsStream((str)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static BufferedImage bg,start,currentBoard = start,pause,gameover,airplane,bee,bigplane,hero0,hero1,bullet;

    public static BufferedImage airplane_ember0,airplane_ember1,airplane_ember2,airplane_ember3;
    public static BufferedImage[] airplane_embers = {airplane_ember0,airplane_ember1,airplane_ember2,airplane_ember3};
    public static BufferedImage bigplane_ember0,bigplane_ember1,bigplane_ember2,bigplane_ember3;
    public static BufferedImage[] bigplane_embers = {bigplane_ember0,bigplane_ember1,bigplane_ember2,bigplane_ember3};
    public static BufferedImage bee_ember0,bee_ember1,bee_ember2,bee_ember3;
    public static BufferedImage[] bee_embers = {bee_ember0,bee_ember1,bee_ember2,bee_ember3};


    public static void main(String[] args){
        Window jpanel = new Window();
        JFrame window = new JFrame();

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setAlwaysOnTop(true);
        window.setSize(WIDTH,HEIGHT);
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        window.add(jpanel);

        class MyMouseAdapter extends MouseAdapter{
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                if (now == GAME_OVER){
                    now = START;
                    jpanel.repaint();
                }
                else if (now == START){
                    now = RUNNING;
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                super.mouseEntered(e);
                if (now == PAUSE){
                    now = RUNNING;
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {
                super.mouseExited(e);
                if (now == RUNNING){
                    jpanel.repaint();
                    now = PAUSE;
                }
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                super.mouseMoved(e);
                if (now == RUNNING){
                    hero.setX(e.getX() - hero.getImageWidth() * 3/5);
                    hero.setY(e.getY() - hero.getImageHeight()/2);
                }
            }
        }

        window.addMouseMotionListener(new MyMouseAdapter());
        window.addMouseListener(new MyMouseAdapter());

        jpanel.action();
    }

    @Override
    public void paint(Graphics g) {
        //super.paint(g);
        Color color = Color.black;
        Font font = new Font("微软雅黑",Font.PLAIN,18);
        g.setColor(color);
        g.setFont(font);
        g.drawImage(bg,0,0,this);
        g.drawString("score:" + hero.getScore(),10,20);
        g.drawString("life:" + hero.getHealth(),10,40);

        drawBoard(g);

        drawHero(g,hero);

        for (int i = 0; i < planes.size(); i++) {
            drawPlane(g,planes.get(i));
        }

        for (int i = 0; i < bullets.size(); i++) {
            drawBullet(g,bullets.get(i));
        }

        for (int i = 0; i < emberPlanes.size(); i++) {
            if (drawEmberPlane(g, emberPlanes.get(i)) > 0){
                i--;
            }
        }
    }

    ArrayList<FlyingObject> planes = new ArrayList<>();
    ArrayList<Bullet> bullets = new ArrayList<>();
    ArrayList<FlyingObject> emberPlanes = new ArrayList<>();

    public static Hero hero = new Hero();

    public void action(){
        class PlaneTimerTask extends TimerTask{
            int count = 0;
            @Override
            public void run() {
                //System.out.println("bullets:" + bullets.size());
                if (now == RUNNING){
                    removeBullet();
                    removePlane();
                    if (count++ % 20 == 0){
                        Bullet[] shoot = hero.shoot();
                        for (int i = 0; i < shoot.length; i++) {
                            bullets.add(shoot[i]);
                        }
                        count = 1;
                    }
                    hero.move();
                    repaint();
                }
            }
        }

        class PlaneCreateTimerTask extends TimerTask{
            @Override
            public void run() {
                if (now == RUNNING){
                    int i = (int) (Math.random() * 10);
                    if (i == 9){
                        planes.add(new BigPlane());
                    }
                    else if(i == 8){
                        planes.add(new Bee());
                    }
                    else{
                        planes.add(new Airplane());
                    }
                }
            }
        }

        timer.schedule(new PlaneCreateTimerTask(),200,1000);
        timer.schedule(new PlaneTimerTask(), 100, 10);
    }

    public void drawBoard(Graphics g){
        switch (now){
            case START:
                currentBoard = Window.start;
                break;
            case PAUSE:
                currentBoard = Window.pause;
                break;
            case GAME_OVER:
                currentBoard = Window.gameover;
                break;
            default:
                currentBoard = null;
        }
        g.drawImage(currentBoard,0,0,null);
    }

    public void drawPlane(Graphics g,FlyingObject fo) {
        g.drawImage(fo.getImage(), fo.getX(), fo.getY(),null);
    }

    public void drawHero(Graphics g,Hero hero) {
        g.drawImage(hero.getImage(), hero.getX(), hero.getY(),null);
        for (int i = 0; i < planes.size(); i++) {
            FlyingObject fo = planes.get(i);
            if (!(fo instanceof Hero)){
                if ((hero.getY() + hero.getImageHeight()/2 >= fo.getY() - 50 && hero.getY() + hero.getImageHeight()/2 <= fo.getY() + fo.getImageHeight() + 50)
                        && (hero.getX() + hero.getImageWidth()/2 >= fo.getX() - 50 && hero.getX() + hero.getImageWidth()/2 <= fo.getX() + fo.getImageWidth() + 50)){
                    fo.setHealth(- 1);
                    hero.setHealth(hero.getHealth() - 1);
                    hero.setDoubleFire(false);
                    if (hero.getHealth() <= 0){
                        now = GAME_OVER;
                        clearAll();
                        this.repaint();
                    }
                }
            }
        }
    }

    public void clearAll(){
        hero = new Hero();
        planes.clear();
        bullets.clear();
        emberPlanes.clear();
    }

    public void drawBullet(Graphics g,Bullet bullet) {
        g.drawImage(bullet.getImage(), bullet.getX(), bullet.getY(),null);
        hitPlane(bullet);
    }

    public int drawEmberPlane(Graphics g,FlyingObject fo){
        BufferedImage[] images = new BufferedImage[4];

        if (fo instanceof Airplane){
            images = airplane_embers;
        }
        else if (fo instanceof BigPlane){
            images = bigplane_embers;
        }
        else {
            images = bee_embers;
        }

        if (fo.getImage() == images[0]){
            fo.setImage(images[1]);
            g.drawImage(fo.getImage(),fo.getX(),fo.getY(),null);
        }
        else if (fo.getImage() == images[1]){
            fo.setImage(images[2]);
            g.drawImage(fo.getImage(),fo.getX(),fo.getY(),null);
        }
        else if (fo.getImage() == images[2]){
            fo.setImage(images[3]);
            g.drawImage(fo.getImage(),fo.getX(),fo.getY(),null);
        }
        else if (fo.getImage() == images[3]){
            emberPlanes.remove(fo);
            return 1;
        }
        else {
            fo.setImage(images[0]);
            g.drawImage(fo.getImage(),fo.getX(),fo.getY(),null);
        }
        return -1;
    }

    public void removePlane(){
        FlyingObject fo;
        for (int i = 0; i < planes.size(); i++) {
            fo = planes.get(i);
            if (fo.getHealth() <= 0){
                if (fo instanceof AddScore){
                    AddScore plane = (AddScore) fo;
                    hero.addScore(plane.addScore());
                }
                if (fo instanceof Reward){
                    Reward plane = (Reward) fo;
                    hero.getReward(plane.rewardType());
                }
                emberPlanes.add(fo);
                planes.remove(fo);
                i--;
                continue;
            }
            if (fo.getY() >= HEIGHT){
                planes.remove(fo);
                i--;
            }
            else{
                fo.move();
            }
        }
    }

    public void removeBullet(){
        for (int i = 0; i < bullets.size(); i++) {
            if (bullets.get(i).getHealth() <= 0){
                bullets.remove(i);
                i--;
            }
            else if(bullets.get(i).getY() < 0){
                bullets.remove(i);
                i--;
            }
            else {
                bullets.get(i).move();
            }
        }
    }

    public void hitPlane(Bullet bullet){
        for (int i = 0; i < planes.size(); i++) {
            FlyingObject plane = planes.get(i);
            if (! (plane instanceof Hero)){
                if ((bullet.getY() >= plane.getY() && bullet.getY() <= plane.getY() + plane.getImageHeight() + 10)
                && (bullet.getX() >= plane.getX()-10 && bullet.getX() <= plane.getX() + plane.getImageWidth())){
                    plane.setHealth(plane.getHealth() - 1);
                    bullet.setHealth(bullet.getHealth() - 1);
                    return;
                }
            }
        }
    }
}
